/**
* @file This file defines the types of module Cil in C
* For mode details, please refer to 
* http://hal.cs.berkeley.edu/cil/api/Cil.html
*
* @author gdhuang@ntu.edu.tw
*/

#ifndef _CIL_TYPE_H_
#define _CIL_TYPE_H_

#include <caml/mlvalues.h>
#include "ocaml_type.h"



/**
* type definitions in module Cil 
*/

DECLARE_RECORD_TYPE(CilFile)

#define get_fileName(record)		Field(record, 0)
#define get_globals(record)			Field(record, 1)
#define get_globinit(record)		Field(record, 2)
#define get_globinitcalled(record)	Field(record, 3)



DECLARE_SUM_TYPE(CilGlobal)
DECLARE_SUM_TAG(
	GType,
	GCompTag,
	GCompTagDecl,
	GEnumTag,
	GEnumTagDecl,
	GVarDecl,
	GVar,
	GFun,
	GAsm,
	GPragma,
	GText)

DECLARE_SUM_TYPE(CilTyp)
DECLARE_SUM_TAG(
	TVoid,
	TInt,
	TFloat,
	TPtr,
	TArray,
	TFun,
	TNamed,
	TComp,
	TEnum,
	TBuiltin_va_list)

DECLARE_SUM_TYPE(CilIkind)
DECLARE_SUM_TAG(
	IChar,
	ISChar,
	IUChar,
    IBool,
	IInt,
	IUInt,
	IShort,
	IUShort,
	ILong,
	IULong,
	ILongLong,
	IULongLong)

DECLARE_SUM_TYPE(CilFkind)
DECLARE_SUM_TAG(
	FFloat,                      
	FDouble,
	FLongDouble)

DECLARE_RECORD_TYPE(CilAttribute)
#define get_Attr(record)		Field(record, 0)
#define CilAttributes OCamlList
DECLARE_SUM_TYPE(CilAttrparam)
DECLARE_SUM_TAG(
	AInt,
	AStr,
	ACons,
	ASizeOf,
	ASizeOfE,
	ASizeOfS,
	AAlignOf,
	AAlignOfE,
	AAlignOfS,
	AUnOp,
	ABinOp,
	ADot,
	AStar,
	AAddrOf,
	AIndex,
	AQuestion)

DECLARE_RECORD_TYPE(CilCompinfo)
#define get_cstruct(record)		Field(record, 0)
#define get_cname(record)		Field(record, 1)
#define get_ckey(record)		Field(record, 2)
#define get_cfields(record)		Field(record, 3)
#define get_cattr(record)		Field(record, 4)
#define get_cdefined(record)	Field(record, 5)
#define get_creferenced(record)	Field(record, 6)



DECLARE_RECORD_TYPE(CilFieldinfo)
#define get_fcomp(record)		Field(record, 0)
#define get_fname(record)		Field(record, 1)
#define get_ftype(record)		Field(record, 2)
#define get_fbitfield(record)	Field(record, 3)
#define get_fattr(record)		Field(record, 4)
#define get_floc(record)		Field(record, 5)

DECLARE_RECORD_TYPE(CilEnuminfo)
#define get_ename(record)		Field(record, 0)
#define get_eitems(record)		Field(record, 1)
#define get_eattr(record)		Field(record, 2)
#define get_ereferenced(record)	Field(record, 3)
#define get_ekind(record)       Field(record, 4)


DECLARE_RECORD_TYPE(CilTypeinfo)
#define get_tname(record)		Field(record, 0)
#define get_ttype(record)		Field(record, 1)
#define get_treferenced(record)	Field(record, 2)



DECLARE_RECORD_TYPE(CilVarinfo)
#define get_vname(record)		Field(record, 0)
#define get_vtype(record)		Field(record, 1)
#define get_vattr(record)		Field(record, 2)
#define get_vstorage(record)	Field(record, 3)
#define get_vglob(record)		Field(record, 4)
#define get_vinline(record)		Field(record, 5)
#define get_vdecl(record)		Field(record, 6)
#define get_vid(record)			Field(record, 7)
#define get_vaddrof(record)		Field(record, 8)
#define get_vreferenced(record)	Field(record, 9)
#define get_vdescr(record)		Field(record, 10)
#define get_vdescrpure(record)	Field(record, 11)





DECLARE_SUM_TYPE(CilStorage)
DECLARE_SUM_TAG(
	NoStorage,
	Static,
	Register,
	Extern)

DECLARE_SUM_TYPE(CilExp)
DECLARE_SUM_TAG(
	Const,		
	Lval,	
	SizeOf,	
	SizeOfE,
	SizeOfStr,	
	AlignOf,		
	AlignOfE,
	UnOp,
	BinOp,
	CastE,
	AddrOf,
	StartOf)

DECLARE_SUM_TYPE(CilConstant)
DECLARE_SUM_TAG(
	CInt64,
	CStr,
	CWStr,
	CChr,
	CReal,
    CEnum)

DECLARE_SUM_TYPE(CilUnop)
DECLARE_SUM_TAG(
	Neg,
	BNot,
	LNot)

DECLARE_SUM_TYPE(CilBinop)
DECLARE_SUM_TAG(
	PlusA,
	PlusPI,
	IndexPI,
	MinusA,
	MinusPI,
	MinusPP,
	Mult,
	Div,
	Mod,
	Shiftlt,
	Shiftrt,
	Lt,
	Gt,
	Le,
	Ge,
	Eq,
	Ne,
	BAnd,
	BXor,
	BOr,
	LAnd,
	LOr)

typedef OCamlTuple CilLval;
#define get_lhost(lval)		Field(lval, 0)
#define get_offset(lval)		Field(lval, 1)

DECLARE_SUM_TYPE(CilLhost)
DECLARE_SUM_TAG(
	Var,
	Mem)

DECLARE_SUM_TYPE(CilOffset)
DECLARE_SUM_TAG(
	Field,
	Index)
DECLARE_SUM_TAG(
    NoOffset)

DECLARE_SUM_TYPE(CilInit)
DECLARE_SUM_TAG(
	SingleInit,
	CompoundInit)

DECLARE_RECORD_TYPE(CilInitinfo)
#define get_init(record)		Field(record, 0)


DECLARE_RECORD_TYPE(CilFundec)
#define get_svar(record)		Field(record, 0)
#define get_sformals(record)	Field(record, 1)
#define get_slocals(record)		Field(record, 2)
#define get_smaxid(record)		Field(record, 3)
#define get_sbody(record)		Field(record, 4)
#define get_smaxstmtid(record)	Field(record, 5)
#define get_sallstmts(record)	Field(record, 6)




DECLARE_RECORD_TYPE(CilBlock)
#define get_battrs(record)		Field(record, 0)
#define get_bstmts(record)		Field(record, 1)


DECLARE_RECORD_TYPE(CilStmt)
#define get_labels(record)		Field(record, 0)
#define get_skind(record)		Field(record, 1)
#define get_sid(record)			Field(record, 2)
#define get_succs(record)		Field(record, 3)
#define get_preds(record)		Field(record, 4)



DECLARE_SUM_TYPE(CilLabel)
DECLARE_SUM_TAG(
	Label,
	Case,
	Default)

DECLARE_SUM_TYPE(CilStmtkind)
DECLARE_SUM_TAG(
	Instr,
	Return,
	Goto,
	Break,
	Continue,
	If,
	Switch,
	Loop,
	Block,
	TryFinally,
	TryExcept)

DECLARE_SUM_TYPE(CilInstr)
DECLARE_SUM_TAG(
	Set,
	Call,
	Asm)

DECLARE_RECORD_TYPE(CilLocation)
#define get_line(record)	Field(record, 0)
#define get_file(record)	Field(record, 1)
#define get_byte(record)	Field(record, 2)


DECLARE_SUM_TYPE(CilTypsig)
DECLARE_SUM_TAG(
	TSArray,
	TSPtr,
	TSComp,
	TSFun,
	TSEnum,
	TSBase)





/**
* type definitions in module CilPrinter 
*/

DECLARE_TYPE(CilPrinter)


/**
* type definitions in module Pretty 
*/

DECLARE_TYPE(PrettyDoc)

#endif
